#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
    #include "wx/mdi.h"
#endif

#include "wx/toolbar.h"
#include "wx/grid.h"
#include "wx/dialog.h"
#include "wx/spinctrl.h"
#include "wx/stattext.h"
#include "wx/sizer.h"

#include <sqlite3.h>
#include <sqlite3util.h>
#include "dbi.h"
#include "mdi.h"
#include <Configuration.h>

//linux header include
#include <sys/types.h>
#include <signal.h>
#include <iostream>
#include <vector>

extern ConfigurationTable gConfig;
extern MainFrame *gPtrframe;
extern wxList my_children;
//IMSI list was saved in TMSITable, short number was saved in sip_buddies
extern IMSITable gIMSITable;
extern SingleColDBI gSIPBuddies;
extern int gs_nFrames;
// ---------------------------------------------------------------------------
// IMSIChildFrame
// ---------------------------------------------------------------------------
// Note that MDI_NEW_WINDOW and MDI_ABOUT commands get passed
// to the parent window for processing, so no need to
// duplicate event handlers here.
BEGIN_EVENT_TABLE(IMSIChildFrame, wxMDIChildFrame)
    EVT_MENU(MDI_CHILD_QUIT, IMSIChildFrame::OnQuit)
    EVT_MENU(MDI_REFRESH, IMSIChildFrame::OnRefresh)
    EVT_MENU(MDI_CHANGE_TITLE, IMSIChildFrame::OnChangeTitle)
    EVT_MENU(MDI_CHANGE_POSITION, IMSIChildFrame::OnChangePosition)
    EVT_MENU(MDI_CHANGE_SIZE, IMSIChildFrame::OnChangeSize)
    EVT_MENU(MDI_GRID_SEND_SMS, IMSIChildFrame::onSendSMS)

#if wxUSE_CLIPBOARD
    EVT_MENU(wxID_PASTE, IMSIChildFrame::OnPaste)
    EVT_UPDATE_UI(wxID_PASTE, IMSIChildFrame::OnUpdatePaste)
#endif // wxUSE_CLIPBOARD

    EVT_GRID_CELL_LEFT_CLICK(IMSIChildFrame::OnSelectLeftCell)
    EVT_GRID_CELL_RIGHT_CLICK(IMSIChildFrame::OnSelectRightCell)
    EVT_SIZE(IMSIChildFrame::OnSize)
    EVT_MOVE(IMSIChildFrame::OnMove)
    //EVT_ACTIVATE(IMSIChildFrame::refreshIMSIList)
    EVT_BUTTON(wxID_ANY, IMSIChildFrame::OnButton)
    EVT_CLOSE(IMSIChildFrame::OnClose)
END_EVENT_TABLE()

BEGIN_EVENT_TABLE(SendSMSModalDialog, wxDialog)
    EVT_BUTTON(wxID_ANY, SendSMSModalDialog::OnButton)
END_EVENT_TABLE()

IMSIChildFrame::IMSIChildFrame(
    wxMDIParentFrame *parent, 
    const wxString& title)
        :wxMDIChildFrame(
            parent, 
            wxID_ANY, 
            title, 
            wxDefaultPosition, 
            wxDefaultSize,
            wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE),
         m_imsilist(&gIMSITable),
         m_callid(&gSIPBuddies),
         m_grid_selx(0), m_grid_sely(0)
         , m_bSelectedCell(false)
{
    my_children.Append(this);

    // this should work for MDI frames as well as for normal ones
    SetSizeHints(100, 100);
    //initialize the grid private popup menu
    m_pGridPrivatePopupMenu = new wxMenu();
    m_pGridPrivatePopupMenu->Append(MDI_GRID_SEND_SMS, _("Send SMS"));
    m_pGridPrivatePopupMenu->Append(MDI_GRID_SEND_VOICE, _("Send Voice"));
    m_pGridPrivatePopupMenu->AppendSeparator();
    m_pGridPrivatePopupMenu->Append(MDI_GRID_RELEASE_MONITOR, _("Release Monitor"));
    m_pGridPrivatePopupMenu->Append(MDI_GRID_MODIFY_INFO, _("Modify Infomation"));
}

IMSIChildFrame::~IMSIChildFrame()
{
    my_children.DeleteObject(this);
    delete m_pGridPrivatePopupMenu;
    delete m_pGrid;
}

void IMSIChildFrame::refreshIMSIList()
{
    std::vector<wxString> imsilist;
    std::vector<wxString>::iterator itr;

    if (m_pGrid == NULL) return;
    m_pGrid->ClearGrid();
    m_pGrid->DeleteRows(0, m_pGrid->GetNumberRows());
    m_pGrid->DeleteCols(0, m_pGrid->GetNumberCols());
    m_pGrid->CreateGrid(0, 0);
    //m_pGrid->AppendRows(2);
    //m_pGrid->AppendCols(2);
    //m_pGrid->SetCellValue(0, 0, _T("testing"));
    m_pGrid->AppendCols(2);
    m_pGrid->SetColLabelValue(0, _("IMSI list"));
    m_pGrid->SetColLabelValue(1, _("Caller ID"));
/*    
    m_imsilist.preIMSIList();
    while (m_imsilist.IMSIhasnext())
    {
        std::string query;
        wxString imsi = m_imsilist.getIMSI();
        imsilist.push_back(imsi);
        m_pGrid->AppendRows(1);
        m_pGrid->SetCellValue(m_pGrid->GetNumberRows() - 1, 0, imsi);
    }
    m_imsilist.stmtClose();
*/
    
    m_callid->prepareQuery("select name, callerid from sip_buddies");
    while (m_callid->hasnext())
    {
        wxString CLID;
        wxString imsi;
        CLID = m_callid->getVal(1);
        imsi = m_callid->getVal(0);
        m_pGrid->AppendRows(1);
        m_pGrid->SetCellValue(m_pGrid->GetNumberRows() - 1, 0, imsi);
        m_pGrid->SetCellValue(m_pGrid->GetNumberRows() - 1, 1, CLID);
    }
    m_callid->stmtClose();
    //autosize make grid without scroll bar, m_pGrid->AutoSize();
    m_pGrid->AutoSizeColumns();
    m_pGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
}

void IMSIChildFrame::OnButton(wxCommandEvent& event)
{
    if (event.GetId() == MDI_CHILD_BUT_REFRESH)
    {
         refreshIMSIList();
    }
    else if (event.GetId() == MDI_CHILD_BUT_DEL) 
    {
         //wxMessageBox(_("testing"), _("testing"), wxOK);
         //open sip_buddies table delete 
         //delete IMSI and short number from all relative tables, 
         //BUT TODO: kicking out of BTS area was not included
         if (m_bSelectedCell) 
         {
             std::string imsi = 
                 std::string(m_pGrid->GetCellValue(m_grid_sely, 0).mb_str());
             std::string query = "delete from sip_buddies where name=\'";
             query.append(imsi);
             query.append("\'");
             m_callid->prepareQuery(query.c_str());
             m_callid->runQuery();
             m_imsilist->delIMSI(imsi.c_str());
             refreshIMSIList();
         }
    }
}

void IMSIChildFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}

void IMSIChildFrame::OnRefresh(wxCommandEvent& WXUNUSED(event))
{
}

void IMSIChildFrame::OnChangePosition(wxCommandEvent& WXUNUSED(event))
{
    Move(10, 10);
}

void IMSIChildFrame::OnChangeSize(wxCommandEvent& WXUNUSED(event))
{
    SetClientSize(100, 100);
}

void IMSIChildFrame::OnChangeTitle(wxCommandEvent& WXUNUSED(event))
{
#if wxUSE_TEXTDLG
    static wxString s_title = _T("Canvas Frame");

    wxString title = wxGetTextFromUser(
        _T("Enter the new title for MDI child"),
        _T("MDI sample question"),
        s_title,
        GetParent()->GetParent());
    if ( !title )
        return;

    s_title = title;
    SetTitle(s_title);
#endif // wxUSE_TEXTDLG
}

void IMSIChildFrame::OnActivate(wxActivateEvent& event)
{
    //if ( event.GetActive() && canvas )
    //     canvas->SetFocus();
}

void IMSIChildFrame::OnSelectLeftCell(wxGridEvent& event)
{
    m_grid_selx = event.GetCol();
    m_grid_sely = event.GetRow();  
    m_bSelectedCell = true;
    m_pGrid->SelectRow(m_grid_sely);

    wxLogStatus(
        _("Selected cell(%d, %d)%s"), 
        m_grid_selx, 
        m_grid_sely, 
        m_pGrid->GetCellValue(m_grid_sely, 0).c_str());
}

void IMSIChildFrame::OnSelectRightCell(wxGridEvent& event)
{
    m_grid_selx = event.GetCol();
    m_grid_sely = event.GetRow();  
    m_bSelectedCell = true;
    m_pGrid->SelectRow(m_grid_sely);
    PopupMenu(m_pGridPrivatePopupMenu);
}

void IMSIChildFrame::onSendSMS(wxCommandEvent& WXUNUSED(event))
{
    wxLogStatus(
        _("Send SMS to %s, %s"), 
        m_pGrid->GetCellValue(m_grid_sely, 0).c_str(), 
        m_pGrid->GetCellValue(m_grid_sely, 1).c_str());
    SendSMSModalDialog dlg(
        this, 
        m_pGrid->GetCellValue(m_grid_sely, 0), 
        m_pGrid->GetCellValue(m_grid_sely, 1));
    dlg.CentreOnParent();
    dlg.ShowModal();
}

void IMSIChildFrame::OnMove(wxMoveEvent& event)
{
    // VZ: here everything is totally wrong under MSW, the positions are
    //     different and both wrong (pos2 is off by 2 pixels for me which seems
    //     to be the width of the MDI canvas border)
    wxPoint pos1 = event.GetPosition(),
            pos2 = GetPosition();
    wxLogStatus(
        wxT("position from event: (%d, %d), from frame (%d, %d)"),
        pos1.x, pos1.y, pos2.x, pos2.y);

    event.Skip();
}

void IMSIChildFrame::OnSize(wxSizeEvent& event)
{
    // VZ: under MSW the size event carries the client size (quite
    //     unexpectedly) *except* for the very first one which has the full
    //     size... what should it really be? TODO: check under wxGTK
    wxSize size1 = event.GetSize(),
           size2 = GetSize(),
           size3 = GetClientSize();
    wxLogStatus(wxT("size from event: %dx%d, from frame %dx%d, client %dx%d"),
                size1.x, size1.y, size2.x, size2.y, size3.x, size3.y);

    event.Skip();
}

void IMSIChildFrame::OnClose(wxCloseEvent& event)
{
    gs_nFrames--;

    event.Skip();
}

#if wxUSE_CLIPBOARD

#include "wx/clipbrd.h"

void IMSIChildFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
{
    wxClipboardLocker lock;
    wxTextDataObject data;
}

void IMSIChildFrame::OnUpdatePaste(wxUpdateUIEvent& event)
{
    wxClipboardLocker lock;
    event.Enable( wxTheClipboard->IsSupported(wxDF_TEXT) );
}
#endif //wxUSE_CLIPBOARD

SendSMSModalDialog::SendSMSModalDialog(wxWindow *parent, wxString imsi, wxString callid)
    :wxDialog(parent, 
        wxID_ANY, wxT(""), 
        wxDefaultPosition, 
        wxDefaultSize, 
        wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
    m_imsi = imsi;
    m_callid = callid;
    wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *sizerHeader = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *sizerSrc = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *sizerText = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer *sizerButtom = new wxBoxSizer(wxHORIZONTAL);
    
    //sizerHeader controls
    sizerHeader->Add(
        new wxStaticText(this, wxID_STATIC, _("IMSI: "), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT),
        0,
        wxALIGN_LEFT|wxALL,
        5);
    sizerHeader->Add(
        new wxStaticText(this, wxID_STATIC, imsi, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT),
        0,
        wxALIGN_LEFT|wxALL,
        5);
    sizerHeader->Add(
        new wxStaticText(this, wxID_STATIC, _("Call Number:"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT),
        0,
        wxALIGN_LEFT|wxALL,
        5);
    sizerHeader->Add(
        new wxStaticText(this, wxID_STATIC, callid, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT),
        0,
        wxALIGN_LEFT|wxALL,
        5);
    //sizer source addresss
    sizerSrc->Add(
        new wxStaticText(this, wxID_STATIC, _("Source number:"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT),
        0,
        wxALIGN_LEFT|wxALL,
        5);
    m_pTxtSrcAddr = new wxTextCtrl(this, wxID_ANY, wxT("10086"), wxDefaultPosition, wxDefaultSize);
    sizerSrc->Add(
        m_pTxtSrcAddr,
        1,
        wxALIGN_LEFT | wxEXPAND | wxALL,
        5);
    //sizerText
    m_pTxtSMSContent = new wxTextCtrl(this, wxID_ANY, wxT(" "), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
    sizerText->Add(
        m_pTxtSMSContent,
        1, 
        //wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL | wxEXPAND | wxALL,
        wxALIGN_LEFT|wxALIGN_RIGHT|wxEXPAND | wxALL,
        5);
    //sizerButtom
    m_btnSend = new wxButton(this, wxID_ANY, _("Send"));
    m_btnCancel = new wxButton(this, wxID_ANY, _("Cancel"));
    sizerButtom->Add(m_btnSend, 0, wxALIGN_RIGHT | wxALL, 5);
    sizerButtom->Add(m_btnCancel, 0, wxALIGN_RIGHT | wxALL, 5);
    //arrange sizer into top sizer
    sizerTop->Add(sizerHeader, 0, wxALIGN_CENTER);
    sizerTop->Add(sizerSrc, 0, wxALIGN_LEFT);
    sizerTop->Add(sizerText, 1, wxALIGN_CENTER| wxEXPAND);
    sizerTop->Add(sizerButtom, 0, wxALIGN_CENTER);
    SetSizer(sizerTop);
    sizerTop->Fit(this);
    sizerTop->SetSizeHints(this);
}

void SendSMSModalDialog::OnButton(wxCommandEvent& evt)
{
    if (evt.GetEventObject() == m_btnCancel)
    {
        Close();
    }
    else if (evt.GetEventObject() == m_btnSend)
    {
        //save SMS content to 
        if (! gConfig.setsms(
            std::string(m_imsi.mb_str()),
            std::string(m_pTxtSMSContent->GetValue().mb_str()),
            std::string(m_pTxtSrcAddr->GetValue().mb_str())))
            wxMessageBox(_("Failed"), _("Sending Short message failed"), wxOK);
        Close();
    }
    else 
    {
        evt.Skip();
    }
}
